package com.clothing.customization.service.impl;

import com.clothing.customization.entity.User;
import com.clothing.customization.repository.OrderRepository;
import com.clothing.customization.repository.UserRepository;
import com.clothing.customization.repository.SystemLogRepository;
import com.clothing.customization.service.AdminDashboardService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 管理员仪表盘服务实现类
 */
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AdminDashboardServiceImpl implements AdminDashboardService {

    private final OrderRepository orderRepository;
    private final UserRepository userRepository;
    private final SystemLogRepository systemLogRepository;
    
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    @Override
    public Map<String, Object> getStats() {
        Map<String, Object> stats = new HashMap<>();
        
        // 获取用户总数
        long totalUsers = userRepository.count();
        long newUsersThisMonth = userRepository.countByCreateTimeBetween(
                Date.from(LocalDate.now().withDayOfMonth(1).atStartOfDay(ZoneId.systemDefault()).toInstant()),
                new Date()
        );
        double userGrowthRate = calculateGrowthRate(totalUsers - newUsersThisMonth, totalUsers);
        
        // 获取订单总数
        long totalOrders = orderRepository.count();
        long newOrdersThisMonth = orderRepository.countByCreateTimeBetween(
                Date.from(LocalDate.now().withDayOfMonth(1).atStartOfDay(ZoneId.systemDefault()).toInstant()),
                new Date()
        );
        double orderGrowthRate = calculateGrowthRate(totalOrders - newOrdersThisMonth, totalOrders);
        
        // 获取总收入 (假设有totalIncome方法)
        double totalIncome = calculateTotalIncome();
        double thisMonthIncome = calculateMonthlyIncome(LocalDate.now().getMonthValue(), LocalDate.now().getYear());
        double incomeGrowthRate = calculateGrowthRate(
                calculateMonthlyIncome(LocalDate.now().minusMonths(1).getMonthValue(), LocalDate.now().minusMonths(1).getYear()),
                thisMonthIncome
        );
        
        // 获取定制申请数量
        long customRequests = orderRepository.countByStatus(0);
        double approvalRate = calculateApprovalRate();
        
        // 构建统计数据
        stats.put("totalUsers", totalUsers);
        stats.put("userGrowth", userGrowthRate);
        stats.put("newUsersThisMonth", newUsersThisMonth);
        
        stats.put("totalOrders", totalOrders);
        stats.put("orderGrowth", orderGrowthRate);
        stats.put("newOrdersThisMonth", newOrdersThisMonth);
        
        stats.put("totalIncome", totalIncome);
        stats.put("incomeGrowth", incomeGrowthRate);
        stats.put("thisMonthIncome", thisMonthIncome);
        
        stats.put("customRequests", customRequests);
        stats.put("approvalRate", approvalRate);
        
        return stats;
    }

    @Override
    public List<Map<String, Object>> getRecentOrders() {
        // 获取最近5条订单
        return orderRepository.findTop4ByOrderByCreateTimeDesc().stream().map(order -> {
            Map<String, Object> map = new HashMap<>();
            map.put("orderNo", order.getOrderNo());
            map.put("customerName", getUsernameById(order.getUserId()));
            map.put("amount", order.getFinalPrice() != null ? order.getFinalPrice() : order.getBudget());
            map.put("status", order.getStatus());
            map.put("createTime", DATETIME_FORMATTER.format(convertToLocalDateTime(order.getCreateTime())));
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    public List<Map<String, Object>> getRecentUsers() {
        // 获取最近5个用户
        return userRepository.findAll().stream()
                .sorted(Comparator.comparing(User::getRegisterTime).reversed())
                .limit(5)
                .map(user -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("username", user.getUsername());
                    map.put("role", user.getRole());
                    map.put("avatar", user.getAvatar());
                    map.put("registerTime", DATETIME_FORMATTER.format(convertToLocalDateTime(user.getRegisterTime())));
                    return map;
                }).collect(Collectors.toList());
    }

    @Override
    public List<Map<String, Object>> getSystemLogs(String type) {
        // 根据类型筛选系统日志
        return systemLogRepository.findTop10ByOrderByCreateTimeDesc().stream()
                .filter(log -> "all".equals(type) || log.getType().equals(type))
                .map(log -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("type", log.getType());
                    map.put("message", log.getMessage());
                    map.put("user", log.getUsername());
                    map.put("time", DATETIME_FORMATTER.format(convertToLocalDateTime(log.getCreateTime())));
                    return map;
                }).collect(Collectors.toList());
    }

    @Override
    public Map<String, Object> getOrderChartData(String type) {
        Map<String, Object> chartData = new HashMap<>();
        List<Map<String, Object>> data = new ArrayList<>();
        List<String> categories = new ArrayList<>();
        
        LocalDate now = LocalDate.now();
        
        switch (type) {
            case "week":
                // 过去7天的数据
                for (int i = 6; i >= 0; i--) {
                    LocalDate date = now.minusDays(i);
                    categories.add(date.format(DATE_FORMATTER));
                    data.add(getOrderDataForDate(date));
                }
                break;
            case "month":
                // 过去30天的数据
                for (int i = 0; i < 30; i += 3) {
                    LocalDate date = now.minusDays(29 - i);
                    categories.add(date.format(DATE_FORMATTER));
                    data.add(getOrderDataForDate(date, date.plusDays(2)));
                }
                break;
            case "year":
                // 一年12个月的数据
                for (int i = 11; i >= 0; i--) {
                    LocalDate monthStart = now.minusMonths(i).withDayOfMonth(1);
                    LocalDate monthEnd = monthStart.with(TemporalAdjusters.lastDayOfMonth());
                    categories.add(monthStart.getMonth().toString());
                    data.add(getOrderDataForDate(monthStart, monthEnd));
                }
                break;
        }
        
        chartData.put("categories", categories);
        chartData.put("data", data);
        
        return chartData;
    }

    @Override
    public Map<String, Object> getUserChartData(String type) {
        Map<String, Object> chartData = new HashMap<>();
        
        if ("role".equals(type)) {
            // 按角色统计用户数量
            List<Map<String, Object>> roleData = new ArrayList<>();
            
            // 因为User实体中role字段是String类型，所以这里应该传递String类型的参数
            long adminCount = userRepository.countByRole("ADMIN");
            long designerCount = userRepository.countByRole("DESIGNER");
            long userCount = userRepository.countByRole("USER");
            
            Map<String, Object> adminMap = new HashMap<>();
            adminMap.put("name", "管理员");
            adminMap.put("value", adminCount);
            roleData.add(adminMap);
            
            Map<String, Object> designerMap = new HashMap<>();
            designerMap.put("name", "设计师");
            designerMap.put("value", designerCount);
            roleData.add(designerMap);
            
            Map<String, Object> userMap = new HashMap<>();
            userMap.put("name", "用户");
            userMap.put("value", userCount);
            roleData.add(userMap);
            
            chartData.put("roleData", roleData);
        } else if ("growth".equals(type)) {
            // 按月份统计用户增长
            List<String> months = new ArrayList<>();
            List<Long> growthData = new ArrayList<>();
            
            LocalDate now = LocalDate.now();
            for (int i = 5; i >= 0; i--) {
                LocalDate monthStart = now.minusMonths(i).withDayOfMonth(1);
                LocalDate monthEnd = monthStart.with(TemporalAdjusters.lastDayOfMonth());
                
                String monthName = monthStart.getMonth().toString();
                months.add(monthName);
                
                long count = userRepository.countByCreateTimeBetween(
                        Date.from(monthStart.atStartOfDay(ZoneId.systemDefault()).toInstant()),
                        Date.from(monthEnd.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant())
                );
                growthData.add(count);
            }
            
            chartData.put("months", months);
            chartData.put("growthData", growthData);
        }
        
        return chartData;
    }
    
    // 辅助方法：计算增长率
    private double calculateGrowthRate(double oldValue, double newValue) {
        if (oldValue == 0) return 100.0;
        return Math.round((newValue - oldValue) / oldValue * 100 * 10) / 10.0;
    }
    
    // 辅助方法：计算总收入
    private double calculateTotalIncome() {
        // 这里应该使用订单仓库查询所有订单总金额
        // 由于没有具体实现，这里返回模拟数据
        return 89032.0;
    }
    
    // 辅助方法：计算月收入
    private double calculateMonthlyIncome(int month, int year) {
        // 这里应该使用订单仓库查询特定月份的订单总金额
        // 由于没有具体实现，这里返回模拟数据
        if (month == LocalDate.now().getMonthValue() && year == LocalDate.now().getYear()) {
            return 12325.0;
        }
        return 12642.0; // 上月收入
    }
    
    // 辅助方法：计算审批通过率
    private double calculateApprovalRate() {
        // 这里应该计算近期定制申请的审批通过率
        // 由于没有具体实现，这里返回模拟数据
        return 85.0;
    }
    
    // 辅助方法：根据用户ID获取用户名
    private String getUsernameById(Long userId) {
        return userRepository.findById(userId)
                .map(User::getUsername)
                .orElse("未知用户");
    }
    
    // 获取单日订单数据
    private Map<String, Object> getOrderDataForDate(LocalDate date) {
        Date startDate = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date endDate = Date.from(date.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
        
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("date", date.format(DATE_FORMATTER));
        
        // 获取当日总订单数
        long totalOrders = orderRepository.countByCreateTimeBetween(startDate, endDate);
        dataMap.put("totalOrders", totalOrders);
        
        // 获取当日完成订单数
        long completedOrders = 0; // 应该调用orderRepository.countByStatusAndCreateTimeBetween(1, startDate, endDate);
        dataMap.put("completedOrders", completedOrders);
        
        // 获取当日取消订单数
        long canceledOrders = 0; // 应该调用orderRepository.countByStatusAndCreateTimeBetween(9, startDate, endDate);
        dataMap.put("canceledOrders", canceledOrders);
        
        return dataMap;
    }
    
    // 获取日期范围内订单数据
    private Map<String, Object> getOrderDataForDate(LocalDate startDate, LocalDate endDate) {
        Date start = Date.from(startDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date end = Date.from(endDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
        
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("startDate", startDate.format(DATE_FORMATTER));
        dataMap.put("endDate", endDate.format(DATE_FORMATTER));
        
        // 获取时间范围内总订单数
        long totalOrders = orderRepository.countByCreateTimeBetween(start, end);
        dataMap.put("totalOrders", totalOrders);
        
        // 获取时间范围内完成订单数
        long completedOrders = 0; // 应该调用orderRepository.countByStatusAndCreateTimeBetween(1, start, end);
        dataMap.put("completedOrders", completedOrders);
        
        // 获取时间范围内取消订单数
        long canceledOrders = 0; // 应该调用orderRepository.countByStatusAndCreateTimeBetween(9, start, end);
        dataMap.put("canceledOrders", canceledOrders);
        
        return dataMap;
    }
    
    // 转换Date到LocalDateTime
    private LocalDateTime convertToLocalDateTime(Date date) {
        return date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }

    private Map<String, Object> sampleOrderData() {
        Map<String, Object> map = new HashMap<>();
        map.put("pending", 5);
        map.put("completed", 8);
        map.put("canceled", 2);
        map.put("total", 15);
        return map;
    }
} 